#include "str.h"
#include <stdio.h>

struct String init_string() {
  struct String str;
  str.mem_id = -1;
  str.length = 0;
  str.s = NULL;
  return str;
}

struct String str_append(struct Memory *mem, struct String dest, char *src) {
  dest = str_catenate(mem, dest, src);
  return dest;
}

int str_len(char *s) {
  if (s == NULL) {
    return 0;
  }
  
  int len = 0;
  while (*s++) {
    ++len;
  }
  s -= len;
  return len;
}

int str_length(struct String str) {
  if (str.s == NULL) {
    return 0;
  }
  
  int len = 0;
  while (*str.s++) {
    ++len;
  }
  str.s -= len;
  return len;
}

struct String str_copy(struct Memory *mem, struct String dest, char *src) {
  int src_len = str_len(src);
  free_memory(mem, dest.mem_id);
  
  struct MemResult res = new_memory(mem, sizeof(char) * (src_len + 1));
  dest.mem_id = res.id;
  dest.s = (char*)res.data;
  dest.length = src_len;

  int i = 0;
  for (; i < src_len; ++i) {
    if (src[i] == '\0') {
      break;
    }
    dest.s[i] = src[i];
  }
  dest.s[i] = '\0';
  return dest;
}

struct String str_catenate(struct Memory *mem, struct String dest, char *src) {
  char *s = dest.s;
  int dest_len = dest.length;
  int src_len = str_len(src);
  
  struct MemResult res = new_memory(mem, sizeof(char) * (dest_len + src_len + 1));
  char *new_str = (char*)res.data;
  int i = 0, j = 0;
  for (; i < dest_len; ++i) {
    if (s[i] == '\0') {
      break;
    }
    new_str[i] = s[i];
  }
  for (; j < src_len; ++i, ++j) {
    if (src[j] == '\0') {
      break;
    }
    new_str[i] = src[j];
  }
  new_str[i] = '\0';

  free_memory(mem, dest.mem_id);
  dest.mem_id = res.id;
  dest.s = new_str;
  dest.length += src_len;
  
  return dest;
}
